home *** CD-ROM | disk | FTP | other *** search
- ; $Id: bar_plot.pro,v 1.4 1997/01/15 03:11:50 ali Exp $
- ;
- ; Copyright (c) 1990-1997, Research Systems, Inc. All rights reserved.
- ; Unauthorized reproduction prohibited.
- ;
-
- pro bar_plot,values,baselines=baselines,colors=colors,barnames=barnames, $
- title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $
- barwidth=barwidth,barspace=barspace,baroffset=baroffset, $
- outline=outline,overplot=overplot,background=background, $
- rotate=rotate
- ;+
- ; NAME:
- ; BAR_PLOT
- ;
- ; PURPOSE:
- ; Create a bar graph, or overplot on an existing one.
- ;
- ; CATEGORY:
- ; Graphics.
- ;
- ; CALLING SEQUENCE:
- ; BAR_PLOT, Values
- ;
- ; INPUTS:
- ; Values: A vector containing the values to be represented by the bars.
- ; Each element in VALUES corresponds to a single bar in the
- ; output.
- ;
- ; KEYWORD PARAMETERS:
- ; BASELINES: A vector, the same size as VALUES, that contains the
- ; base value associated with each bar. If not specified,
- ; a base value of zero is used for all bars.
- ;
- ; COLORS: A vector, the same size as VALUES, containing the color index
- ; to be used for each bar. If not specified, the colors are
- ; selected based on spacing the color indices as widely as
- ; possible within the available colors (specified by D.N_COLORS).
- ;
- ; BARNAMES: A string array, containing one string label per bar.
- ; If the bars are vertical, the labels are placed beneath
- ; them. If horizontal (rotated) bars are specified, the labels
- ; are placed to the left of the bars.
- ;
- ; TITLE: A string containing the main title to for the bar plot.
- ;
- ; XTITLE: A string containing the title for the X axis.
- ;
- ; YTITLE: A string containing the title for the Y axis.
- ;
- ; BASERANGE: A floating-point scalar in the range 0.0 to 1.0, that
- ; determines the fraction of the total available plotting area
- ; (in the direction perpendicular to the bars) to be used.
- ; If not specified, the full available area is used.
- ;
- ; BARWIDTH: A floating-point value that specifies the width of the bars
- ; in units of "nominal bar width". The nominal bar width is
- ; computed so that all the bars (and the space between them,
- ; set by default to 20% of the width of the bars) will fill the
- ; available space (optionally controlled with the BASERANGE
- ; keyword).
- ;
- ; BARSPACE: A scalar that specifies, in units of "nominal bar width",
- ; the spacing between bars. For example, if BARSPACE is 1.0,
- ; then all bars will have one bar-width of space between them.
- ; If not specified, the bars are spaced apart by 20% of the bar
- ; width.
- ;
- ; BAROFFSET: A scalar that specifies the offset to be applied to the
- ; first bar, in units of "nominal bar width". This keyword
- ; allows, for example, different groups of bars to be overplotted
- ; on the same graph. If not specified, the default offset is
- ; equal to BARSPACE.
- ;
- ; OUTLINE: If set, this keyword specifies that an outline should be
- ; drawn around each bar.
- ;
- ; OVERPLOT: If set, this keyword specifies that the bar plot should be
- ; overplotted on an existing graph.
- ;
- ; BACKGROUND: A scalar that specifies the color index to be used for
- ; the background color. By default, the normal IDL background
- ; color is used.
- ;
- ; ROTATE: If set, this keyword indicates that horizontal rather than
- ; vertical bars should be drawn. The bases of horizontal bars
- ; are on the left, "Y" axis and the bars extend to the right.
- ;
- ; OUTPUTS:
- ; A bar plot is created, or an existing one is overplotted.
- ;
- ; EXAMPLE:
- ; By using the overplotting capability, it is relatively easy to create
- ; stacked bar charts, or different groups of bars on the same graph.
- ;
- ; For example, if ARRAY is a two-dimensional array of 5 columns and 8
- ; rows, it is natural to make a plot with 5 bars, each of which is a
- ; "stacked" composite of 8 sections. First, create a 2D COLORS array,
- ; equal in size to ARRAY, that has identical color index values across
- ; each row to ensure that the same item is represented by the same color
- ; in all bars.
- ;
- ; With ARRAYS and COLORS defined, the following code fragment
- ; illustrates the creation of stacked bars (note that the number of rows
- ; and columns is arbitrary):
- ;
- ; !Y.RANGE = [0,ymax] ; Scale range to accommodate the total bar lengths.
- ; BASE = INTARR(NROWS)
- ; FOR I = 0, NROWS-1 DO BEGIN
- ; BAR_PLOT, ARRAY(*,I), COLORS=COLORS(*,I), BASELINES=BASE, $
- ; BARWIDTH=0.75, BARSPACE=0.25, OVER=(I GT 0)
- ; BASE = BASE + ARRAY(*,I)
- ; ENDFOR
- ;
- ; To plot each row of ARRAY as a clustered group of bars within the same
- ; graph, use the BASERANGE keyword to restrict the available plotting
- ; region for each set of bars. The sample code fragment below
- ; illustrates this method:
- ;
- ; FOR I = 0, NROWS-1 DO $
- ; BAR_PLOT, ARRAY(*,I), COLORS=COLORVECT, BARWIDTH=0.8,BARSPACE=0.2, $
- ; BAROFFSET=I*((1.0+BARSPACE)*NCOLS), OVER=(I GT 0), BASERANGE=0.19
- ;
- ; where NCOLS is the number of columns in ARRAY, and COLORVECT is a
- ; vector containing the color indices to be used for each group of
- ; bars. (In this example, each group uses the same set of colors, but
- ; this could easily be changed.)
- ;
- ; MODIFICATION HISTORY:
- ; August 1990, T.J. Armitage, RSI, initial programming. Replacement
- ; for PLOTBAR and OPLOTBAR routines written by William Thompson.
- ;
- ; September 1990, Steve Richards, RSI, changed defaults to improve the
- ; appearance of the bar plots in the default mode. Included
- ; spacing the bars slightly.
- ;-
- if (n_params(d) eq 0) then begin ;Print call & return if no parameters
- print,'bar_test,values,baselines=baselines,colors=colors,barnames=barnames,$'
- print,' title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $'
- print,' barwidth=barwidth,barspace=barspace,baroffset=baroffset, $'
- print,' outline=outline,overplot=overplot,background=background, $'
- print,' rotate=rotate'
- return
- endif
-
- nbars=n_elements(values) ; Determine number of bars
- ; Baselines (bars extend from baselines through values); default=0
- if not(keyword_set(baselines)) then baselines=intarr(nbars)
- ; Default colors spaced evenly in current color table
- if not(keyword_set(colors)) then $
- colors=fix((!d.n_colors/float(nbars))*(indgen(nbars)+0.5))
- ; Labels for the individual bars; none by default
- if not(keyword_set(barnames)) then barnames=strarr(nbars)+' '
- ; Main title
- if not(keyword_set(title)) then title=''
- ; Centered title under X-axis
- if not(keyword_set(xtitle)) then xtitle=''
- ; Title for Y-axis
- if not(keyword_set(ytitle)) then ytitle=''
- ; Fraction (0-1) of full X range to use
- if not(keyword_set(baserange)) then baserange=1.0
- ; Space betw. bars, taken from nominal bar widths; default is none
- If not(keyword_set(barspace)) then barspace=0.2
- ; Bar width scaling factor, relative to nominal
- if not(keyword_set(barwidth)) then barwidth=1.0 - barspace - barspace / nbars
- ; Initial X offset, in scaled bar widths; default is none
- if not(keyword_set(baroffset)) then baroffset=barspace/barwidth
- ; Outline of bars; default is none
- outline = keyword_set(outline)
- ; Overplot (do not erase the existing display); default is to create new plot
- overplot = keyword_set(overplot)
- ; Background color index; defaults to 0 (usually black) if not specified
- if not(keyword_set(background)) then background=0
- ; Rotate (make horizontal bars); default is vertical bars
- rotate = keyword_set(rotate)
-
- if (rotate) then begin ;Horizontal bars
- if (!x.range[0] eq 0) and (!x.range[1] eq 0) $ ;Determine range for X-axis
- then $
- xrange=[(min(baselines)<min(values)), $ ;Minimum of bases & values
- (max(baselines)>max(values))] $ ;Maximum of bases & values
- else xrange=!x.range ;Or, use range specified
- if (!y.range[0] eq 0) and (!y.range[1] eq 0) $ ;Plot will calculate
- then $ ; defaults for X, but not
- yrange = [0, n_elements(values)] $ ; for Ys, so fill in here.
- else $
- yrange=!y.range ;Axis perpend. to bars
- yticks=1 ;Suppress ticks in plot
- ytickname=strarr(2)+' '
- xticks=0
- xtickname=strarr(1)+''
- endif else begin ;Vertical bars
- if (!y.range[0] eq 0) and (!y.range[1] eq 0) $ ;Determine range for Y-axis
- then $
- yrange=[(min(baselines)<min(values)), $ ;Minimum of bases & values
- (max(baselines)>max(values))] $ ;Maximum of bases & values
- else yrange=!y.range ;Or, use range specified
- xrange=!x.range ;Axis perpend. to bars
- xticks=1 ;Suppress ticks in plot
- xtickname=strarr(2)+' '
- yticks=0
- ytickname=strarr(1)+''
- endelse
- if (overplot eq 0) then $ ;Create new plot, no data
- plot,[values],/nodata,title=title,xtitle=xtitle,ytitle=ytitle, $
- noerase=overplot,xrange=xrange,yrange=yrange,xticks=xticks, $
- xtickname=xtickname,yticks=yticks,ytickname=ytickname, $
- xstyle=1,ystyle=1,/data,background=background
- if (rotate) then begin ;Horizontal bars
- base_win=!y.window ;Window range in Y
- scal_fact=!x.s ;Scaling factors
- tick_scal_fact=!y.s ;Tick scaling factors
- endif else begin ;Vertical bars
- base_win=!x.window ;Window range in X
- scal_fact=!y.s ;Scaling factors
- tick_scal_fact=!x.s ;Tick scaling factors
- endelse
- winrange=baserange*(base_win[1]-base_win[0]) ;Normal. window range
- barsize=barwidth*winrange/nbars ;Normal. bar width
- winoffset=base_win[0]+(baroffset*barsize) ;Normal. first offset
- bases=scal_fact[0]+(scal_fact[1]*baselines) ;Baselines, in normal coor.
- normal=scal_fact[0]+(scal_fact[1]*values) ;Values, in normal coor.
- barstart=indgen(nbars)*(barsize+barspace*(winrange/nbars)) ;Coor. at left edges
- tickv=winoffset+barstart+(0.5*barsize) ;Tick coor. (centered)
- for i=0,nbars-1 do begin ;Draw the bars
- width=winoffset+[barstart[i],barstart[i], $ ;Compute bar width
- (barstart[i]+barsize),(barstart[i]+barsize)]
- length=[bases[i],normal[i],normal[i],bases[i]] ;Compute bar length
- if (rotate) then begin ;Horizontal bars
- x=length ;X-axis is "length" axis
- y=width ;Y-axis is "width" axis
- endif else begin ;Vertical bars
- x=width ;X-axis is "width" axis
- y=length ;Y-axis is "length" axis
- endelse
- polyfill,x,y,color=colors[i],/normal ;Polyfill with color
- if (outline) then plots,x,y,/normal ;Outline using !p.color
- endfor
-
- tickv=(tickv-tick_scal_fact[0])/tick_scal_fact[1] ;Locations of the ticks
- if (rotate) then $ ;Label the bars (Y-axis)
- axis,yaxis=0,ystyle=1,yticks=(nbars-1),ytickv=tickv,ytickname=barnames, $
- yticklen=0.0 $
- else $ ;Label the bars (X-axis)
- axis,xaxis=0,xstyle=1,xticks=(nbars-1),xtickv=tickv,xtickname=barnames, $
- xticklen=0.0
- return
- end
-